﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Chapter12.Code03.Code03
{
    using System.Collections;

    public class Farm<T> : IEnumerable<T>
        where T : Animal
    {
        private List<T> animals = new List<T>();

        public List<T> Animals
        {
            get { return animals; }
        }

        public IEnumerator<T> GetEnumerator()
        {
            return animals.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return animals.GetEnumerator();
        }

        public void MakeNoises()
        {
            foreach (T animal in animals)
            {
                animal.MakeANoise();
            }
        }

        public void FeedTheAnimals()
        {
            foreach (T animal in animals)
            {
                animal.Feed();
            }
        }

        public Farm<Cow> GetCows()
        {
            Farm<Cow> cowFarm = new Farm<Cow>();
            foreach (T animal in animals)
            {
                cowFarm.Animals.Add(animal as Cow);
            }
            return cowFarm;
        }

        public Farm<U> GetSpecies<U>()
            where U : T
        {
            Farm<U> speciesFarm = new Farm<U>();
            foreach (T animal in animals)
            {
                if (animal is U)
                {
                    speciesFarm.Animals.Add(animal as U);
                }
            }
            return speciesFarm;
        }

        //方式1
        public static implicit operator List<Animal>(Farm<T> farm)
        {
            List<Animal> result = new List<Animal>();
            foreach (T animal in farm)
            {
                result.Add(animal);
            }
            return result;
        }

        public static Farm<T> operator +(Farm<T> farm1, List<T> farm2)
        {
            Farm<T> result = new Farm<T>();
            foreach (T animal in farm1)
            {
                result.Animals.Add(animal);
            }
            foreach (T animal in farm2)
            {
                if (!result.animals.Contains(animal))
                {
                    result.Animals.Add(animal);
                }
            }
            return result;
        }

        public static Farm<T> operator +(List<T> farm1, Farm<T> farm2)
        {
            return farm2 + farm1;
        }

        //方式2
        public static implicit operator Farm<Animal>(Farm<T> farm)
        {
            Farm<Animal> result = new Farm<Animal>();
            foreach (T animal in farm)
            {
                result.Animals.Add(animal);
            }
            return result;
        }

        public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2)
        {
            Farm<T> result = new Farm<T>();
            foreach (T animal in farm1)
            {
                result.Animals.Add(animal);
            }
            foreach (T animal in farm2)
            {
                if (!result.Animals.Contains(animal))
                {
                    result.Animals.Add(animal);
                }
            }
            return result;
        }
    }
}
